package com.qzsoft.system.modules.permission.index.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qzsoft.jeemis.common.constant.Constant;
import com.qzsoft.jeemis.common.service.BaseService;
import com.qzsoft.jeemis.common.utils.ConvertDictUtils;
import com.qzsoft.jeemis.common.utils.DateUtils;
import com.qzsoft.jeemis.platform.security.user.SecurityUser;
import com.qzsoft.jeemis.platform.security.user.UserDetail;
import com.qzsoft.system.modules.permission.deptJob.dto.SysDeptJobDTO;
import com.qzsoft.system.modules.permission.index.dao.IndexMapper;
import com.qzsoft.system.modules.permission.index.dto.FlowDTO;
import com.qzsoft.system.modules.permission.index.dto.MyProcessInstanceDTO;
import com.qzsoft.system.modules.permission.index.dto.SysScheduleDTO;
import com.qzsoft.system.modules.permission.index.service.IndexService;
import com.qzsoft.system.modules.permission.index.utils.DateUill;
import com.qzsoft.system.repository.sys.entity.SysScheduleEntity;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.converters.DateConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl extends BaseService implements IndexService {
    @Autowired
    private IndexMapper mapper;

    @Override
    public IPage<FlowDTO> selectFlowPage(Map<String, Object> params) {
        IPage<FlowDTO> page = this.getPage(params, Constant.CREATE_DATE, false, FlowDTO.class);
        QueryWrapper<FlowDTO> queryWrapper = Wrappers.query();
        queryWrapper.eq("iden.USER_ID_", this.basegetLoginUser().getUsername());
        IPage<FlowDTO> pageData = mapper.selectFlowList(page, queryWrapper);
        pageData = ConvertDictUtils.formatDicDataPage(pageData);
        return pageData;
    }

    @Override
    public List<Map<String, String>> selectFlowList(Map<String, Object> params) throws Exception {
        ConvertUtilsBean convertUtils = BeanUtilsBean.getInstance().getConvertUtils();
        DateConverter dateConverter = new DateConverter();
        dateConverter.setPattern("yyyy-MM-dd HH:mm:ss");
        convertUtils.register(dateConverter, String.class);
        if ("2".equals(params.get("flowType"))) {
            QueryWrapper<MyProcessInstanceDTO> queryWrapper = Wrappers.query();
            queryWrapper.eq("hiTask.auditor_id", this.basegetLoginUser().getUsername())
                    .ne("hiTask.audit_type", "start");
            List<MyProcessInstanceDTO> list = mapper.selectCreatedListByUserId(queryWrapper);
            return ConvertDictUtils.formatDicDataList(list).stream().map(bean -> {
                try {
                    return BeanUtils.describe(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }).collect(Collectors.toList());
        } else if ("3".equals(params.get("flowType"))) {
            QueryWrapper<MyProcessInstanceDTO> queryWrapper = Wrappers.query();
            queryWrapper.like("pi.cc_person", this.basegetLoginUser().getUsername());
            List<MyProcessInstanceDTO> list = mapper.selectCarbonCopyListByUserId(queryWrapper);
            return ConvertDictUtils.formatDicDataList(list).stream().map(bean -> {
                try {
                    return BeanUtils.describe(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }).collect(Collectors.toList());
        } else if ("4".equals(params.get("flowType"))) {
            QueryWrapper<MyProcessInstanceDTO> queryWrapper = Wrappers.query();
            queryWrapper.eq("pi.apply_user_id", this.basegetLoginUser().getUsername())
                    .eq("pi.flow_status", "processing");
            List<MyProcessInstanceDTO> list = mapper.selectCreatedListByUserId(queryWrapper);
            return ConvertDictUtils.formatDicDataList(list).stream().map(bean -> {
                try {
                    return BeanUtils.describe(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }).collect(Collectors.toList());
        } else if ("5".equals(params.get("flowType"))) {
            QueryWrapper<MyProcessInstanceDTO> queryWrapper = Wrappers.query();
            queryWrapper.eq("pi.apply_user_id", this.basegetLoginUser().getUsername())
                    .ne("pi.flow_status", "processing");
            List<MyProcessInstanceDTO> list = mapper.selectCreatedListByUserId(queryWrapper);
            return ConvertDictUtils.formatDicDataList(list).stream().map(bean -> {
                try {
                    return BeanUtils.describe(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }).collect(Collectors.toList());
        } else {
            QueryWrapper<FlowDTO> queryWrapper = Wrappers.query();
            queryWrapper.eq("iden.USER_ID_", this.basegetLoginUser().getUsername());
            List<FlowDTO> list = mapper.selectFlowList(queryWrapper);
            return ConvertDictUtils.formatDicDataList(list).stream().map(bean -> {
                try {
                    return BeanUtils.describe(bean);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }).collect(Collectors.toList());
        }
    }

    @Override
    public void saveSchedule(SysScheduleEntity entity) {
        UserDetail user = SecurityUser.getUser();
        Date date = new Date();
        entity.setId(UUID.randomUUID().toString());
        entity.setCreator(user.getId());
        entity.setCreateDate(date);
        entity.setUpdater(user.getId());
        entity.setUpdateDate(date);
        mapper.saveSchedule(entity);
    }

    @Override
    public List<Map<String, Object>> selectScheduleList(Map<String, Object> params) {
        QueryWrapper<SysScheduleDTO> queryWrapper = Wrappers.query();
        queryWrapper.eq("creator", SecurityUser.getUser().getId())
                .ge("start_time", DateUill.getTimesMonthmorning())
                .lt("start_time", DateUill.getTimesMonthnight())
                .orderByAsc("start_time");
        List<Map<String, Object>> result = new ArrayList<>(31);
        List<SysScheduleDTO> dtoList = mapper.selectScheduleList(queryWrapper);
        for (int i = 0; i < dtoList.size(); i++) {
            String date = DateUtils.format(dtoList.get(i).getStartTime());
            if (i != 0 && date.equals(result.get(result.size() - 1).get("date"))) {
                Map<String, Object> lastMap = result.get(result.size() - 1);
                List<String> list = (List<String>) lastMap.get("content");
                list.add(dtoList.get(i).getTitle());
            } else {
                Map<String, Object> map = new HashMap<>();
                map.put("date", date);
                List<String> list = new ArrayList<>();
                list.add(dtoList.get(i).getTitle());
                map.put("content", list);
                result.add(map);
            }
        }
        return result;
    }

    @Override
    public int selectFlowListCnt(Map<String, Object> params) {
        QueryWrapper<FlowDTO> queryWrapper = Wrappers.query();
        queryWrapper.eq("iden.USER_ID_", this.basegetLoginUser().getUsername());
        int cnt = mapper.selectFlowListCnt(queryWrapper);
        return cnt;
    }
}
